import { ApiProperty } from "@nestjs/swagger";
import {
    Column,
    Entity,
    ManyToMany, PrimaryGeneratedColumn,
    Tree,
    TreeChildren,
    TreeParent
} from "typeorm";
import { SysRole } from "./SysRole";

@Entity()
@Tree("closure-table")
export class SysMenu {

    @ApiProperty({description: '菜单主键', example: 1})
    @PrimaryGeneratedColumn({ comment: '菜单主键'})
    menuId: number;

    @ApiProperty({description: '菜单名称', example: '首页'})
    @Column({name: 'menu_name', comment: '菜单名称', length: 10, })
    menuName: string;

    @ApiProperty({description: "父级ID", example: 0})
    @Column({name: "parent_id", comment: "父级ID", nullable: true})
    parentId: number;

    @ApiProperty({description: "菜单路由", example: '/home'})
    @Column({comment: "菜单路由", length: 50, nullable: true})
    url: string;

    @ApiProperty({description: "排序", example: 0})
    @Column({name: "order_num", comment: "排序", nullable: true})
    orderNum: number;

    @ApiProperty({description: "图标", example: "el-icon-menu"})
    @Column({comment: "图标", length: 50, nullable: true})
    icon: string;

    @ApiProperty({description: "子集"})
    @TreeChildren()
    children: SysMenu[];

    @ApiProperty({description: "父亲"})
    @TreeParent()
    parent: SysMenu;


    constructor(menuId?: number, menuName?: string, parentId?: number, url?: string, orderNum?: number, icon?: string, children?: SysMenu[], parent?: SysMenu, roles?: SysRole[]) {
        this.menuId = menuId;
        this.menuName = menuName;
        this.parentId = parentId;
        this.url = url;
        this.orderNum = orderNum;
        this.icon = icon;
        this.children = children;
        this.parent = parent;
        this.roles = roles;
    }

    /**
     * 关联关系
     */
    @ManyToMany(type => SysRole, role => role.menus, {createForeignKeyConstraints: false})
    roles: SysRole[]


    public static toTree(menus: SysMenu[]): SysMenu[] {
        let menuList: SysMenu[] = [];

        menuList = menus.filter(item => item.parentId == null);
        // menus = menus.filter(item => item.parentId != null);

        for (let root of menuList) {
            root.children = this.findChild(root.menuId, menus)
        }

        return menuList;
    }
    
    static findChild(pid, menus): any[] {
        let children = [];
        for (let menu of menus) {
            if (menu.parentId == null) {
                continue;
            }
            if (menu.parentId == pid) {
                children = [...children, menu];
                menu.children = this.findChild(menu.menuId, menus);
            }
        }
        if (children.length == 0) {
            return null;
        }
        return children;
    }

}
